package cn.szzsi._admin;

import cn.szzsi.service.*;
import cn.szzsi.common.bean.dto.Msg;
import cn.szzsi.common.bean.dto.TreeNode;
import cn.szzsi.common.excel.PoiRender;
import cn.szzsi.common.kit.CommonUtil;
import cn.szzsi.common.model.*;
import cn.szzsi.common.model.Deposit.DepositType;
import cn.szzsi.common.model.MemberAttribute.AttributeType;
import cn.szzsi.validator.MemberValidator;
import com.jfinal.aop.Before;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.render.Render;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 后台类 - 会员
 * 
 */

public class MemberController extends BaseAdminController<Member> {
	private Member member;
	private String shopId;

	// 是否已存在 ajax验证
	public void checkUsername() {
		String username = getPara("member.username","");
		if (Member.dao.isExistByUsername(username)) {
			renderText("false");
		} else {
			renderText("true");
		}
	}
		
	// 列表
	public void list() {
		render("list.html");
	}


	public void ajaxlist(){
		shopId=getAttr("shopId");
		String sourceType=getPara("sourceType");
		String sqlExceptSelect = "select a.username,a.phone,a.code,a.sex,a.createDate,a.isAccountLocked,a.id,a.realname,b.name as memberRankname,c.code topCode,c.username topUsername,c.realname topRealname from mall_member a left join mall_member_rank b on memberRankId=b.id left join mall_member c on a.pid=c.id where 1 = 1 ";
		//因开元一通客户需要导出正式会员,在此做单独处理,后续如有需求会再处理
		if (StrKit.notBlank(getProperty()) && StrKit.notBlank(getKeyword())) {
			sqlExceptSelect += "and " + getProperty() + " like '%" + getKeyword() + "%'";
		}

		if(shopId != null){
			sqlExceptSelect += " and a.shopId = '"+shopId+"'";
		}
		if(StrKit.notBlank(sourceType)){
			sqlExceptSelect+=" and a.sourceType="+sourceType+"";
		}

		sqlExceptSelect += " order by a." + getOrderBy() +" "+ getOrderType();
		List<Member> list = Member.dao.find(sqlExceptSelect);

		renderJson(list);
	}

	public void changeParent(){
		try {
			String id = getPara("id");
			String pcode = getPara("pcode");
			Member m = Member.dao.findById(id);
			List<Member> pms = Member.dao.find("select * from mall_member where code = ?",pcode);
			if(pms == null||pms.size() < 1){
				renderJson(Msg.fail(1,"所选上级不存在"));
				return;
			}
			if(pms.size()>1){
				renderJson(Msg.fail(1,"所选上级重复，请联系检查"));
				return;
			}
			if(m == null){
				renderJson(Msg.fail(1,"用户不存在"));
				return;
			}
			renderJson(Msg.success(MemberService.service.changeParent(m, pms.get(0))));
		}catch (Exception e){
			renderJson(Msg.fail(0,"调用出错"));
		}

	}

	//重置会员密码
	public void resetMemberPassword(){
		String memberId=getPara("id");
		Member member= Member.dao.findById(memberId);
		member.set("password", DigestUtils.md5Hex("123456")).set("isAccountLocked",0).set("loginFailureCount",0).update();
		renderJson(Msg.SUCCESS);

	}

	public void close(){
		Member m = Member.dao.findById(getPara("id"));
		if(m != null){
			if(m.getBoolean("isAccountLocked")){
				m.set("isAccountLocked",false).update();
			}else{
				m.set("isAccountLocked",true).update();
			}
		}
		renderJson(Msg.SUCCESS);
	}

	// 设为总监
	public void head() {
		String id=getPara("id");
		Member m = Member.dao.findById(id);
		if(m.get("head").equals("NO")){
			m.set("head","YES");
		}else{
			m.set("head","NO");
		}
		m.update();
		renderHtml("<script>alert('设置成功');history.go(-1);</script>");
	}

	//分销树形关系
	public void fxrelation(){
        String id = getPara("id");
        Member m = Member.dao.findById(id);
        setAttr("m",m);
        setAttr("checked",false);
        render("fxrelation.html");
    }

    public void fxtreenode(){
		//根据上级的id来找到所有的下级
        //like查法，本节点的pids+本节点的id
        String pid = getPara("pid");
        String id = getPara("id");
        if(StrKit.isBlank(id)){
            id = pid;
        }

        if(StringUtils.isNotBlank(id)){
            Member m = Member.dao.findById(id);

                String pids = m.getStr("id").equals("0")?"":m.getStr("id");

                String sql = "select id,username,pid,pids from mall_member where pid = ? ";
                String sqllike = "select id,username,pid,pids from mall_member where pids like ? ";
                List<Member> lm = Member.dao.find(sql,pids);
                if(lm != null && lm.size() > 0){
                    List<TreeNode> ltn = new ArrayList<TreeNode>();
                    List<Member> tmpList = new ArrayList<Member>();
                    for(Member member:lm){
                        TreeNode tn = new TreeNode();
                        tn.setId(member.getStr("id"));
                        tn.setName(member.getStr("username"));
                        pids = member.getStr("pids").equals("0")?"":member.getStr("pids")+",";
                        tmpList = Member.dao.find(sqllike,pids+member.getStr("id")+"%");
                        if(tmpList != null && tmpList.size()>0){
                            tn.setIsParent(true);
                        }else{
                            tn.setIsParent(false);
                        }
                        ltn.add(tn);
                    }
                    renderJson(ltn);
                    return;
                }else{
                    TreeNode tn = new TreeNode();
                    tn.setId("0");
                    tn.setName("叶子结点");
                    tn.setIsParent(false);
                    renderJson(tn);
                    return;
                }
        }
    }
		
	// 添加
	public void add() {
		setAttr("allMemberRank", getAllMemberRank());
		setAttr("enabledMemberAttributeList", getEnabledMemberAttributeList());
		render(CommonUtil.TEMPLATE_PATH+"/admin/member_input.html");
	}

	// 编辑
	public void edit() {
		id = getPara("id", id);
		if (StrKit.notBlank(id)) {
			member = Member.dao.findById(id);
			setAttr("member", member);
		}
		setAttr("enabledMemberAttributeList", getEnabledMemberAttributeList());
		setAttr("allMemberRank", getAllMemberRank());
		render(CommonUtil.TEMPLATE_PATH+"/admin/member_input.html");
	}
	
	// 保存
	@Before({MemberValidator.class,Tx.class})
	public void save() {
		member = getModel(Member.class);
		String rePassword = getPara("rePassword","");
		
		if (member.getBigDecimal("deposit").compareTo(new BigDecimal("0")) < 0) {
			addActionError("预存款不允许小于0");
			return;
		}
		if (!StringUtils.equalsIgnoreCase(member.getStr("password"), rePassword)) {
			addActionError("两次密码输入不一致!");
			return;
		}
		
		Map<String, String> memberAttributeMap = new HashMap<String, String>();
		List<MemberAttribute> enabledMemberAttributeList = MemberAttribute.dao.getEnabledMemberAttributeList();
		for (MemberAttribute memberAttribute : enabledMemberAttributeList) {
			String parameterValues = getPara(memberAttribute.getStr("id"),"");
			if (memberAttribute.getBoolean("isRequired") && (StrKit.notBlank(parameterValues))) {
				addActionError(memberAttribute.getStr("name") + "不允许为空!");
				return;
			}
			
			int attributeType = MemberAttribute.dao.findById(memberAttribute.getStr("id")).getAttributetype().ordinal();
			if (StringUtils.isNotEmpty(parameterValues)) {
				if (attributeType == AttributeType.number.ordinal()) {
					Pattern pattern = Pattern.compile("^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)(?:\\.\\d+)?");
					Matcher matcher = pattern.matcher(parameterValues);
					if (!matcher.matches()) {
						addActionError(memberAttribute.getStr("name") + "只允许输入数字!");
						return;
					}
				}
				if (attributeType == AttributeType.alphaint.ordinal()) {
					Pattern pattern = Pattern.compile("[a-zA-Z]+");
					Matcher matcher = pattern.matcher(parameterValues);
					if (!matcher.matches()) {
						addActionError(memberAttribute.getStr("name") + "只允许输入字母!");
						return;
					}
				}
				if (memberAttribute.getAttributetype() == AttributeType.email) {
					Pattern pattern = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
					Matcher matcher = pattern.matcher(parameterValues);
					if (!matcher.matches()) {
						addActionError(memberAttribute.getStr("name") + "E-mail格式错误!");
						return;
					}
				}
				if (attributeType == AttributeType.date.ordinal()) {
					Pattern pattern = Pattern.compile("\\d{4}[\\/-]\\d{1,2}[\\/-]\\d{1,2}");
					Matcher matcher = pattern.matcher(parameterValues);
					if (!matcher.matches()) {
						addActionError(memberAttribute.getStr("name") + "日期格式错误!");
						return;
					}
				}
				if (attributeType == AttributeType.area.ordinal()) {
					if (!Area.dao.isAreaPath(parameterValues)) {
						addActionError(memberAttribute.getStr("name") + "地区错误!");
						return;
					}
				}
				if (attributeType == AttributeType.select.ordinal() || attributeType == AttributeType.checkbox.ordinal()) {
					List<String> attributeOptionList = memberAttribute.getAttributeOptionList();
					if (!attributeOptionList.contains(parameterValues)) {
						addActionError("参数错误!");
						return;
					}
				}
				memberAttributeMap.put(memberAttribute.getStr("id"), parameterValues);
			}
		}
		member.set("username",member.getStr("username").toLowerCase());
		member.set("password", DigestUtils.md5Hex(member.getStr("password")));
		member.set("safeQuestion",null);
		member.set("safeAnswer",null);
		member.set("isAccountLocked",false);
		member.set("loginFailureCount",0);
		member.set("passwordRecoverKey",null);
		member.set("lockedDate",null);
		member.set("loginDate",new Date());
		member.set("registerIp",getRequest().getRemoteAddr());
		member.set("loginIp",null);
		saved(member);
		
		// 保存会员属性
		if (memberAttributeMap != null && memberAttributeMap.size() > 0){
			member.setMemberAttributeMap(memberAttributeMap);
		}		
		
		// 预存款记录
		if (member.getBigDecimal("deposit").compareTo(new BigDecimal("0")) > 0) {
			Deposit deposit = new Deposit();
			deposit.set("depositType",DepositType.adminRecharge.ordinal());
			deposit.set("credit",member.getBigDecimal("deposit"));
			deposit.set("debit",new BigDecimal("0"));
			deposit.set("balance",member.getBigDecimal("deposit"));
			deposit.set("member_id",member.getStr("id"));
			deposit.save(deposit);
		}
		redirect("/admin/member/list");
	}
		
	// 更新
	@Before({MemberValidator.class,Tx.class})
	public void update() {		
		member = getModel(Member.class);
		String rePassword = getPara("rePassword","");
		
		if (member.getBigDecimal("deposit").compareTo(new BigDecimal("0")) < 0) {
			addActionError("预存款不允许小于0");
			return;
		}
		if (member.getStr("password") != null && !StringUtils.equalsIgnoreCase(member.getStr("password"), rePassword)) {
			addActionError("两次密码输入不一致!");
			return;
		}
		
		Map<String, String> memberAttributeMap = new HashMap<String, String>();
		List<MemberAttribute> enabledMemberAttributeList = MemberAttribute.dao.getEnabledMemberAttributeList();
		for (MemberAttribute memberAttribute : enabledMemberAttributeList) {
			String parameterValues = getPara(memberAttribute.getStr("id"),"");
			
			if (memberAttribute.getBoolean("isRequired") && (StrKit.notBlank(parameterValues))) {
				addActionError(memberAttribute.getStr("name") + "不允许为空!");
				return;
			}
			int attributeType = MemberAttribute.dao.findById(memberAttribute.getStr("id")).getAttributetype().ordinal();
			if (StringUtils.isNotEmpty(parameterValues)) {
				if (attributeType == AttributeType.number.ordinal()) {
					Pattern pattern = Pattern.compile("^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)(?:\\.\\d+)?");
					Matcher matcher = pattern.matcher(parameterValues);
					if (!matcher.matches()) {
						addActionError(memberAttribute.getStr("name") + "只允许输入数字!");
						return;
					}
				}
				if (attributeType == AttributeType.alphaint.ordinal()) {
					Pattern pattern = Pattern.compile("[a-zA-Z]+");
					Matcher matcher = pattern.matcher(parameterValues);
					if (!matcher.matches()) {
						addActionError(memberAttribute.getStr("name") + "只允许输入字母!");
						return;
					}
				}
				if (memberAttribute.getAttributetype() == AttributeType.email) {
					Pattern pattern = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
					Matcher matcher = pattern.matcher(parameterValues);
					if (!matcher.matches()) {
						addActionError(memberAttribute.getStr("name") + "E-mail格式错误!");
						return;
					}
				}
				if (attributeType == AttributeType.date.ordinal()) {
					Pattern pattern = Pattern.compile("\\d{4}[\\/-]\\d{1,2}[\\/-]\\d{1,2}");
					Matcher matcher = pattern.matcher(parameterValues);
					if (!matcher.matches()) {
						addActionError(memberAttribute.getStr("name") + "日期格式错误!");
						return;
					}
				}
				if (attributeType == AttributeType.area.ordinal()) {
					if (!Area.dao.isAreaPath(parameterValues)) {
						addActionError(memberAttribute.getStr("name") + "地区错误!");
						return;
					}
				}
				if (attributeType == AttributeType.select.ordinal() || attributeType == AttributeType.checkbox.ordinal()) {
					List<String> attributeOptionList = memberAttribute.getAttributeOptionList();
					if (!attributeOptionList.contains(parameterValues)) {
						addActionError("参数错误!");
						return;
					}
				}
				memberAttributeMap.put(memberAttribute.getStr("id"), parameterValues);
			}
		}
		
		// 保存会员属性
		if (memberAttributeMap != null && memberAttributeMap.size() > 0){
			member.setMemberAttributeMap(memberAttributeMap);
		}	
		
		Member persistent = Member.dao.findById(member.getStr("id"));
		BigDecimal previousDeposit = persistent.getBigDecimal("deposit");
		BigDecimal currentDeposit = member.getBigDecimal("deposit");
		
		//密码是否有修改	
		if (StringUtils.isEmpty(member.getStr("password"))) {
			member.set("password",persistent.getStr("password"));
		} else {
			member.set("password", DigestUtils.md5Hex(member.getStr("password")));
		}
		updated(member);
		
		// 预存款记录
		if (currentDeposit.compareTo(previousDeposit) > 0) {
			Deposit deposit = new Deposit();
			deposit.set("depositType",DepositType.adminRecharge.ordinal());
			deposit.set("credit",currentDeposit.subtract(previousDeposit));
			deposit.set("debit",new BigDecimal("0"));
			deposit.set("balance",currentDeposit);
			deposit.set("member_id",persistent.getStr("id"));
			deposit.save(deposit);
		} else if (member.getBigDecimal("deposit").compareTo(previousDeposit) < 0) {
			Deposit deposit = new Deposit();
			deposit.set("depositType",DepositType.adminRecharge.ordinal());
			deposit.set("credit",new BigDecimal("0"));
			deposit.set("debit",previousDeposit.subtract(currentDeposit));
			deposit.set("balance",currentDeposit);
			deposit.set("member_id",persistent.getStr("id"));
			deposit.save(deposit);
		}
		redirect("/admin/member/list");
	}
		
	// 删除
	@Before(Tx.class)
	public void delete() {
		ids = getParaValues("ids");
		if (ids != null && ids.length > 0) {
			for (String id : ids) {
				Member member = Member.dao.findById(id);
				String username = member.getStr("username");
				// 检查是否有预付款
				if (member.getBigDecimal("deposit").compareTo(new BigDecimal("0")) > 0) {
					ajaxJsonErrorMessage("会员[" + username + "]预付款余额不为零，删除失败！");
					return;
				}
				// 充值记录
				List<Deposit> depositList = member.getDepositList();
				if (depositList != null && depositList.size() > 0){
					ajaxJsonErrorMessage("会员[" + username + "]存在充值记录，删除失败！");
					return;
				}				
				// 检查是否有订单
				List<Orders> orderList = member.getOrderList();
				if (orderList != null && orderList.size() > 0){
					ajaxJsonErrorMessage("会员[" + username + "]存在订单，删除失败！");
					return;
				}
				// 收件箱是否存在消息
				List<Message> inboxMessage = member.getInboxMessageList();
				if (inboxMessage != null && inboxMessage.size() > 0){
					ajaxJsonErrorMessage("会员[" + username + "]收件箱有内容，删除失败！");
					return;
				}
				// 发件箱是否存在消息
				List<Message> outboxMessage = member.getOutboxMessageList();
				if (outboxMessage != null && outboxMessage.size() > 0){
					ajaxJsonErrorMessage("会员[" + username + "]发件箱有内容，删除失败！");
					return;
				}				
				Db.deleteById("member_memberattributemapstore", "member_id", member.getStr("id"));
				member.delete();
			}
			ajaxJsonSuccessMessage("删除成功！");
		}
	}


	public void getAllParentForm(){
		String id=getPara("id");
		setAttr("id",id);
		render("all_parent.html");
	}

	public void getAllParent(){
    	String id=getPara("id");
		List<Member> list = new ArrayList<Member>();
		String pids = Db.queryStr("select pids from mall_member where id = '"+id+"'");
		if(!pids.equals("0")){
			String[] ss = pids.split(",");
			for(String s:ss){
				list.add(Member.dao.findById(s));
			}
		}
		renderJson(list);
	}


	public void getUserBackMoneyForm(){
		String id=getPara("id");
		setAttr("id",id);
		render("user_back_money.html");
	}

	public void getUserBackMoney(){
		String pid = getPara("id");
		if(StrKit.notBlank(pid) && !pid.equals("0")){
			String sql = "select bb.addMoney,bb.level,bb.rate,bb.createDate,m.username from mall_user_balance_detail bb left join mall_member" +
					" m on bb.fromuid = m.id where bb.mid = '"+pid+"' and bb.type='0' order by bb.createDate desc";
			List<Record> lr = Db.find(sql);
			renderJson(lr);
		}
	}
	//会员导出
	public void exportMember(){
		shopId=getAttr("shopId");
		String memberRank=getPara("memberLevel","1");//会员等级:1正式会员,2准会员
        String sqlExceptSelect = "select a.username,a.phone,a.code,(case when a.sex=1 then '男' when a.sex=2 then '女'  else '未知' end)sex,c.code topCode,a.createDate,a.realname,b.name as memberRankname from mall_member a left join mall_member_rank b on memberRankId=b.id left join mall_member c on a.pid=c.id where 1 = 1 ";

        System.out.println(sqlExceptSelect);
        if (StrKit.notBlank(getProperty()) && StrKit.notBlank(getKeyword())) {
            sqlExceptSelect += "and " + getProperty() + " like '%" + getKeyword() + "%'";
        }

        if(shopId != null){
            sqlExceptSelect += " and a.shopId = '"+shopId+"'";
        }

		//因开元一通客户需要导出正式会员,在此做单独处理,后续如有需求会再处理
		if("1".equals(memberRank)){//正式会员
			sqlExceptSelect += " and b.id='dafc86f6aee04a8aa9c722689ef65b3y'";
		}else if("2".equals(memberRank)){//准会员
			sqlExceptSelect += " and b.id='sf60982c5faf48cb8f59a492a73a6b2c'";
		}
        sqlExceptSelect += " order by a." + getOrderBy() +" "+ getOrderType();
		System.out.println(sqlExceptSelect);
		List<Member> list = Member.dao.find(sqlExceptSelect);
		String[] header={"用户名","联系方式","编码","会员等级","性别","推荐人编码","注册日期"};
		String[] columns={"username","phone","code","memberRankname","sex","topCode","createDate"};
		Render poirender = PoiRender.me(list).fileName("member.xls").headers(header).sheetName("正式会员").columns(columns);
		render(poirender);
    }


	//预存款充值(商户后台给用户充值)
	public void addmoney(){
		shopId=getAttr("shopId");
		String memberId=getPara("memberId");//用户id
		Member member= Member.dao.findById(memberId);
		BigDecimal addDeposit=new BigDecimal(getPara("deposit"));//充值金额
		//更新会员余额结果
		UserBalanceService.service.updateBalance(member,addDeposit);
		//资金交易明细
		UserBalanceDetailService.service.saveAdminRecharge(memberId,addDeposit, UserBalanceDetail.BalanceType.adminRecharge.ordinal(),shopId);
		//MemberService.service.handleDeposit(member,addDeposit,Deposit.DepositType.adminPayment,Deposit.AccountType.CREDIT);
		renderJson(Msg.SUCCESS);
	}

	//积分充值
	public void addpoint(){
		String memberId=getPara("memberId");//用户id
		int addPoint=getParaToInt("point");
		Member member= Member.dao.findById(memberId);
		//更新会员余额结果
		UserBalanceService.service.updatePoint(member,addPoint);
		//积分交易明细
		UserPointDetailService.service.saveInfo(memberId,addPoint, UserPointDetail.PointDetailType.adminRecharge.ordinal(),"后台代充值");
		renderJson(Msg.SUCCESS);
	}
		
	// 获取所有会员等级
	public List<MemberRank> getAllMemberRank() {
		return MemberRank.dao.getAll(shopId);
	}
	
	// 获取已启用的会员注册项
	public List<MemberAttribute> getEnabledMemberAttributeList() {
		return MemberAttribute.dao.getEnabledMemberAttributeList();
	}

}
